#ifndef __DEBUG__
// For printing purposes
#define __DEBUG__ 0
#endif

#include <iostream>
#include <cstdint>

#include "../VAR.hpp"
#include "../TERM.hpp"
#include "../EXPRESSION.hpp"
#include "../ADD.hpp"
#include "../SUB.hpp"
#include "../MIN.hpp"
#include "../MAX.hpp"
#include "../CEIL.hpp"
#include "../FLOOR.hpp"

using namespace std;

// Global variables for printing and debugging purposes
int expr_depth = -1;
int bin_expr_depth = -1;

void test6() {
  constexpr VariableTerm<1> t1;
  constexpr VariableTerm<2> t2;
  constexpr VariableTerm<3> t3;
  constexpr VariableTerm<4> t4;
  constexpr VariableTerm<5> t5;
  constexpr VariableTerm<6> pN;
  constexpr VariableTerm<7> pT;

  auto expr01 = MAX(MAX(0,CEIL(t1+t2-1,2)),CEIL(16*t2-pN-14,16));
  if (__DEBUG__) cout << endl << "\tEXPR01 evals to " << endl <<  expr01 << endl;

  auto expr02 = MIN(MIN(FLOOR(pT+pN-2,16),FLOOR(16*t2+pN+14,16)),FLOOR(8*t1+8*t2+pN+15,16));
  if (__DEBUG__) cout << endl << "\tEXPR02 evals to " << endl <<  expr02 << endl;

  auto expr03 = MAX(MAX(MAX(0,CEIL(t1+t2-124,125)),CEIL(16*t2-pN-998,1000)),CEIL(16*t3-pN-998,1000));
  if (__DEBUG__) cout << endl << "\tEXPR03 evals to " << endl <<  expr03 << endl;

  auto expr04 =
    MIN(MIN(MIN(MIN(FLOOR(8*t1+pN+7,500),FLOOR(pT+pN-2,1000)),FLOOR(16*t2+pN+14,1000)),FLOOR(16*t3+pN+14,1000)),FLOOR(8*t1+8*t2+pN+15,1000));
  if (__DEBUG__) cout << endl << "\tEXPR04 evals to " << endl <<  expr04 << endl;
  
  auto expr05 =
    MAX(MAX(MAX(MAX(MAX(0,8*t1+8*t2),16*t1+1),16*t2-pN),16*t3-pN),1000*t4-pN);
  if (__DEBUG__) cout << endl << "\tEXPR05 evals to " << endl <<  expr05 << endl;

  auto expr06 = MIN(MIN(MIN(MIN(MIN(pT-2,16*t2+14),16*t3+14),1000*t4+998),8*t1+8*t2+15),16*t1+pN+15);
  if (__DEBUG__) cout << endl << "\tEXPR06 evals to " << endl <<  expr06 << endl;

  auto expr07 = MAX(MAX(16*t2,t5+1),-16*t1+2*t5-15);
  if (__DEBUG__) cout << endl << "\tEXPR07 evals to " << endl <<  expr07 << endl;

  auto expr08 = MIN(MIN(-16*t1+2*t5,16*t2+15),t5+pN);
  if (__DEBUG__) cout << endl << "\tEXPR08 evals to " << endl <<  expr08 << endl;

  auto expr09 = MAX(16*t3,t5+1);
  if (__DEBUG__) cout << endl << "\tEXPR09 evals to " << endl <<  expr09 << endl;

  auto expr10 = MIN(16*t3+15,t5+pN);
  if (__DEBUG__) cout << endl << "\tEXPR10 evals to " << endl <<  expr10 << endl;

}

int main (void) {
  test6();
}
